﻿using Furion.RemoteRequest.Extensions;
using IP2Region;
using System;
using System.IO;

namespace Queer.Util.Helper
{
    public class IpLocationHelper
    {
        #region IP位置查询

        public static string GetIpLocation(string ipAddress)
        {
            string ipLocation = string.Empty;

            if (!IsInnerIP(ipAddress))
            {
                if (string.IsNullOrEmpty(ipAddress) || ipAddress.Length < 6)
                    return string.Empty;

                using (var ipSearch = new DbSearcher(Environment.CurrentDirectory + $"{Path.DirectorySeparatorChar}DB{Path.DirectorySeparatorChar}ip2region.db"))
                {
                    ipLocation = ipSearch.MemorySearch(ipAddress).Region;
                }

                if (string.IsNullOrEmpty(ipLocation))
                    ipLocation = GetIpLocationFromIpIp(ipAddress);

                if (string.IsNullOrEmpty(ipLocation))
                    ipLocation = GetIpLocationFromPCOnline(ipAddress);
            }
            else
                ipLocation = "局域网";

            return ipLocation;
        }

        private static string GetIpLocationFromIpIp(string ipAddress)
        {
            string url = "http://freeapi.ipip.net/" + ipAddress;
            string result = url.GetAsStringAsync().GetAwaiter().GetResult();
            string ipLocation = string.Empty;
            if (!string.IsNullOrEmpty(result))
            {
                result = result.Replace("\"", string.Empty);
                var resultArr = result.Split(',');
                ipLocation = resultArr[1] + " " + resultArr[2];
                ipLocation = ipLocation.Trim();
            }
            return ipLocation;
        }

        private static string GetIpLocationFromPCOnline(string ipAddress)
        {
            var url = "http://whois.pconline.com.cn/ip.jsp?ip=" + ipAddress;
            var result = url.SetContentType("text/html; charset=gb2312")
                .GetAsStringAsync()
                .GetAwaiter()
                .GetResult();

            string ipLocation = string.Empty;
            if (!string.IsNullOrEmpty(result))
            {
                var resultArr = result.Split(' ');
                ipLocation = resultArr[0].Replace("省", "  ").Replace("市", "");
                ipLocation = ipLocation.Trim();
            }
            return ipLocation;
        }

        #endregion

        #region 判断是否是外网IP

        public static bool IsInnerIP(string ipAddress)
        {
            if (string.IsNullOrWhiteSpace(ipAddress))
                return true;

            long ipNum = GetIpNum(ipAddress);

            long aBegin = GetIpNum("10.0.0.0");
            long aEnd = GetIpNum("10.255.255.255");
            long bBegin = GetIpNum("172.16.0.0");
            long bEnd = GetIpNum("172.31.255.255");
            long cBegin = GetIpNum("192.168.0.0");
            long cEnd = GetIpNum("192.168.255.255");
            var isInnerIp = IsInner(ipNum, aBegin, aEnd) || IsInner(ipNum, bBegin, bEnd) || IsInner(ipNum, cBegin, cEnd) || ipAddress.Equals("127.0.0.1");
            return isInnerIp;
        }

        /// <summary>
        /// 把IP地址转换为Long型数字
        /// </summary>
        /// <param name="ipAddress">IP地址字符串</param>
        /// <returns></returns>
        private static long GetIpNum(string ipAddress)
        {
            string[] ip = ipAddress.Split('.');
            long a = int.Parse(ip[0]);
            long b = int.Parse(ip[1]);
            long c = int.Parse(ip[2]);
            long d = int.Parse(ip[3]);

            long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
            return ipNum;
        }

        private static bool IsInner(long userIp, long begin, long end)
        {
            return (userIp >= begin) && (userIp <= end);
        }

        #endregion
    }
}
